/*******************************************************************************
*
*   FILE NAME:
*       Matrix.h - Matrix class definition
*
*   DESCRIPTION:
*       Defines a 4x4 matrix.
*
*******************************************************************************/
#pragma once

#include "Types.h"
#include "Vector3.h"

class Matrix
{
public:
    static const Matrix Identity;

    float32 M11, M12, M13, M14;
    float32 M21, M22, M23, M24;
    float32 M31, M32, M33, M34;
    float32 M41, M42, M43, M44;

    Matrix( void );
    Matrix( float32 m11, float32 m12, float32 m13, float32 m14,
            float32 m21, float32 m22, float32 m23, float32 m24,
            float32 m31, float32 m32, float32 m33, float32 m34,
            float32 m41, float32 m42, float32 m43, float32 m44 );
    Matrix( const float32* matrix_data );
    Matrix( const Matrix& other );
    ~Matrix( void );

    Matrix& operator=( const Matrix& other );
    friend boolean operator==( const Matrix& mat1, const Matrix& mat2 );
    friend boolean operator!=( const Matrix& mat1, const Matrix& mat2 );
    friend Matrix operator+( const Matrix& mat1, const Matrix& mat2 );
    friend Matrix operator-( const Matrix& mat1, const Matrix& mat2 );
    friend Matrix operator*( const Matrix& mat1, const Matrix& mat2 );
    friend Matrix operator*( const Matrix& mat, float32 scalar );
    friend Matrix operator*( float32 scalar, const Matrix& mat );
    friend Matrix operator/( const Matrix& mat1, const Matrix& mat2 );
    friend Matrix operator/( const Matrix& mat, float32 divider );
    
    static Matrix Add( const Matrix& mat1, const Matrix& mat2 );
    static Matrix Divide( const Matrix& mat1, const Matrix& mat2 );
    static Matrix Divide( const Matrix& mat, float32 divider );
    static Matrix Invert( const Matrix& mat );
    static Matrix Multiply( const Matrix& mat1, const Matrix& mat2 );
    static Matrix Multiply( const Matrix& mat, float32 scalar );
    static Matrix Subtract( const Matrix& mat1, const Matrix& mat2 );
    static Matrix Transpose( const Matrix& mat );
    
    static void Add( const Matrix& mat1, const Matrix& mat2, Matrix& result );
    static void Divide( const Matrix& mat1, const Matrix& mat2, Matrix& result );
    static void Divide( const Matrix& mat, float32 divider, Matrix& result );
    static void Invert( const Matrix& mat, Matrix& result );
    static void Multiply( const Matrix& mat1, const Matrix& mat2, Matrix& result );
    static void Multiply( const Matrix& mat, float32 scalar, Matrix& result );
    static void Subtract( const Matrix& mat1, const Matrix& mat2, Matrix& result );
    static void Transpose( const Matrix& mat, Matrix& result );
    
    static Matrix CreateLookAt( const Vector3& camera, const Vector3& target, const Vector3& up );
    static Matrix CreatePerspectiveFieldOfView( float32 field_of_view, float32 aspect_ratio, float32 near_plane, float32 far_plane );
    
    static void CreateLookAt( const Vector3& camera, const Vector3& target, const Vector3& up, Matrix& result );
    static void CreatePerspectiveFieldOfView( float32 field_of_view, float32 aspect_ratio, float32 near_plane, float32 far_plane, Matrix& result );
    
protected:

private:

};
